﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CTkitMvvmDemo
{
    public class MessagerBase
    {
    }

    public class Test
    {
        public static void Run()
        {
            var rec = new StringMessageReceiver();
            EventAggregator.Instance.Send(new StringMessage("Hello1"));

            var num = new NumberMessageReceiver();
            EventAggregator.Instance.Send(new NumberMessage(42));
        }
    }

    /// <summary>
    /// 抽象类  接收者在【事件簿】上注册不同的信息TMessage 并留有接收消息后要执行的方法的接口
    /// 这里注册是将接收者自己和出发方法两个参数配合给到【事件簿】
    /// </summary>
    /// <typeparam name="TMessage"></typeparam>
    public abstract class MessageReceiver<TMessage>{

        protected MessageReceiver()
        {
            EventAggregator.Instance.Register<TMessage>(this, Receive);
        }
        public abstract void Receive(TMessage m);
    }

    record StringMessage(string message); 
    /// <summary>
    /// 收信者
    /// </summary>
    class StringMessageReceiver : MessageReceiver<StringMessage>
    {
        public override void Receive(StringMessage m)
        {
            string str = m.message;
            Console.WriteLine(str);
        }
    }
     record NumberMessage(double value); 
    /// <summary>
    /// 收信者
    /// </summary>
    class NumberMessageReceiver : MessageReceiver<NumberMessage>
    { 
       public override void Receive(NumberMessage m)
        {
            double str = m.value;
            Console.WriteLine(str);
        }
    }


    /// <summary>
    /// 事件集中订阅和发送者 即【事件簿】
    /// </summary>
    class EventAggregator
    {
        public static EventAggregator Instance { get; } = new();

        record MessageReceiver(object Receiver, Action<object> Method);
        private Dictionary<Type, List<MessageReceiver>> events = new();

        public void Register<TMessage>(object receiver, Action<TMessage> method)
        {
            var type = typeof(TMessage);
            if (!events.ContainsKey(type))
            {
                events[type] = new();
            }
            events[type].Add(
                new(
                    receiver,
                    o => method( (TMessage)o )
                    )
                );
        }
        public void Send<TMessage>(TMessage message)
        {
            var type = typeof(TMessage);
            if (!events.ContainsKey(type)) { return; }
            foreach (var rec in events[type])
            {
                rec.Method.Invoke(message);
            }
        }

    }
}
